<?php

    error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING);
	require_once 'include/inc.config.php';
	require_once 'load_wact.php';



 	require_once APP_ROOT . "model/common/user.php";
	require_once APP_ROOT . "model/common/session.php";
	require_once APP_ROOT . "model/common/parameters.php";
	require_once APP_ROOT . "model/common/price.php";
	require_once APP_ROOT . "model/common/subscription.php";
	require_once APP_ROOT . "model/common/payment.php";
	require_once APP_ROOT . "model/common/date.php";

 	define('PAYPAL_DEBUG',1);
    info_log(' ------------------------------------------------------------------');
    //info_log(' Started IPN message: ');

 	event_log();

 	$txn_type = $_POST['txn_type'];
 	$subscr_id = $_POST['subscr_id'];
    $user_id = $_POST['custom'];
    $receiver_email = $_POST['receiver_email'];

 	info_log(' IPN message: '.$txn_type.' Subscription ID: '.$subscr_id.'');

 //if (PAYPAL_DEBUG) print_r($_REQUEST);

  	$paypal_email = Parameters::getPaypalEmail();
  	$mode = Parameters::getRunningMode();
  	if ($mode) $paypal_url = 'www.paypal.com';
  	else $paypal_url = 'www.sandbox.paypal.com';

 	// read the post from PayPal system and add 'cmd'
	$req = 'cmd=_notify-validate';
    $report = '';
	foreach ($_POST as $key => $value) {
		$value = urlencode(stripslashes($value));
		$req .= "&$key=$value";
		$report .= "&$key=$value";
	}

	info_log("REQUEST: ".$report."\n");

	// post back to PayPal system to validate
	$header = "";
	$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
	$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
	$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
	$fp = fsockopen($paypal_url, 80, $errno, $errstr, 30);

// check for test_ipn variable
// The Sandbox sets the variable test_ipn with a value of 1 in the HTTP response back
// to your IPN page. The purpose of this variable is to clearly differentiate between live
// and Sandbox IPN, so you can write your processing programs to work with either
// live or Sandbox IPN. If the test_ipn variable is not present in the HTTP response,
// you are working with Live PayPal.
// assign posted variables to local variables
$test_ipn = (isset($_POST['test_ipn'])) ? $_POST['test_ipn'] : false;

if ($test_ipn) info_log(' THIS IS A TEST IPN message: '.$txn_type.' Subscription: '.$subscr_id.'\n ');
else info_log(' THIS IS A LIVE IPN message: '.$txn_type.' Subscription: '.$subscr_id.'\n ');
$ds =& new DataSpace();

if ($txn_type=='subscr_signup') {
  info_log(' THIS IS A SUBSCRIPTION SIGNUP IPN message: ');
  $subscr_date = $_POST['subscr_date'];
  $start_date_ts = strtotime($subscr_date);
  $tz =& new MyTimeZone();
  $start_date_ts = $tz->timeGMT($start_date_ts);

  $payer_email = $_POST['payer_email'];
  $payer_id = $_POST['payer_id'];

  $period3 = $_POST['period3'];
  $amount3 = $_POST['amount3'];
  $mc_amount3 = $_POST['mc_amount3'];
  if (!$amount3) $amount3 = $mc_amount3;
  $recurring = $_POST['recurring']; if (!$recurring) $recurring = 0;
  $subscr_id = $_POST['subscr_id'];
  $user_id = $_POST['custom'];
  $type = $_POST['item_number'];
  $ds->set('paypal_subscription_id',$subscr_id);
  $start_date =  gmdate("Y-m-d H:i",$start_date_ts);
  info_log(' Subscription start date  -'.$subscr_id.' Start date: '.$start_date);
  $ds->set('start_date',$start_date);
  $ds->set('type',$type);
  $ds->set('amount',$amount3);
  $ds->set('recurring',$recurring);
  $ds->set('status',1);

  $expireTS = Subscription::getExpirationDate($type, $start_date_ts);
  $expire_date =  gmdate("Y-m-d H:i",$expireTS);
  $ds->set('next_rebill_date',$expire_date);
  $ds->set('user_id',$user_id);
  info_log(' Subscription signup IPN received  -'.$subscr_id.' Expire date: '.$expire_date);

} else if ($txn_type=='subscr_payment')   {
  info_log(' THIS IS A SUBSCRIPTION PAYMENT IPN message: ');
  $subscr_id = $_POST['subscr_id'];
  $subscription_record =& Subscription::getRecord( $subscr_id );
  if ($subscription_record) $subscription_id = $subscription_record->get('id');
  $payment_status = $_POST['payment_status'];
  $status = @!strcmp($payment_status,'Completed');
  $pending_reason = $_POST['pending_reason'];
  $reason_code = $_POST['reason_code'];
  $reason = @($reason_code)?$reason_code:$pending_reason;
  $txn_id = $_POST['txn_id'];

  $subscr_id = $_POST['subscr_id'];
  $user_id = $_POST['custom'];

  $payment_date = $_POST['payment_date'];
  info_log(' PAYMENT: '.$payment_status.' Subscription ID:'.$subscr_id.' '.$txn_id.' '.$status. ' reason: '.$reason.' date: '.$payment_date);

  $payment_date_ts = @strtotime($payment_date);
  $tz =& new MyTimeZone();
  $payment_date_ts = $tz->timeLocal($payment_date_ts);
  $now = $tz->timeNowLocal();
  if ($payment_date_ts) $p_date =  gmdate("Y-m-d",$payment_date_ts);
  else $p_date =  gmdate("Y-m-d",$now);
  $payment_amount = floatval($_POST['mc_gross']);
  $payment_currency = $_POST['mc_currency'];

  $ds->set('date',$p_date);
  $ds->set('txn_id',$txn_id);
  $ds->set('subscription_id',$subscription_id);
  $ds->set('status',$status);
  $ds->set('amount',$payment_amount);
  $ds->set('paypal_subscription_id',$subscr_id);
  $ds->set('user_id',$user_id);

  $receiver_email = $_POST['receiver_email'];
  $payer_email = $_POST['payer_email'];
  info_log(' Subscription payment IPN received  - Status: '.$payment_status.' Subscription ID:'.$subscr_id.' '.$txn_id.' '.$receiver_email);

} else if ($txn_type=='subscr_eot')   {
	info_log(' THIS IS A SUBSCRIPTION TERMINATION IPN message: ');
	$subscr_id = $_POST['subscr_id'];
	info_log(' Subscription termination IPN received  -'.$subscr_id);
} else if ($txn_type=='subscr_cancel')   {
    info_log(' THIS IS A SUBSCRIPTION CANCELLATION IPN message: ');
	$subscr_id = $_POST['subscr_id'];
	info_log(' Subscription cancellation IPN received  -'.$subscr_id);
} else if ($txn_type=='subscr_failed')   {
    info_log(' THIS IS A SUBSCRIPTION FAILURE IPN message: ');
	$subscr_id = $_POST['subscr_id'];
	info_log(' Subscription failure IPN received  -'.$subscr_id);
}


if (!$fp) {
// HTTP ERROR
} else {
	fputs ($fp, $header . $req);
	if (!feof($fp))  {
 		$res = fgets ($fp, 1024);
 		info_log(" PAYPAL verification response: ".$res." \n ");
 		if (true) { //(strcmp ($res, "VERIFIED") == 0)
    		info_log(' Subscription Processing started -'.$subscr_id);
    		if (strcmp($receiver_email,$paypal_email) != 0) {
    			info_log(' Spoofed IPN? -'.$receiver_email.' '.$paypal_email);
    			err_log(' Spoofed IPN? -'.$receiver_email.' '.$paypal_email);
    			return;
    		}
    		if ($txn_type=='subscr_signup') {
    			$exist = Subscription::existSubscription($subscr_id);
    			$id = Subscription::insertSubscription($ds);
    			if ($id && !$exist) info_log(' New Subscription inserted or updated -'.$subscr_id.' id:'.$id);
    			else info_log(' Subscription already exists - UPDATED!'.$subscr_id.' ');

    			User::updateUserPaypalID($user_id, $payer_email, $payer_id);
                info_log(' User paypal email is updated: ('.$user_id.') '.$payer_email.' '.$payer_id);
    		} else if ($txn_type=='subscr_payment')   {
    			info_log(' DO PAYMENT processing... -'.$txn_id.' '.$subscr_id);
    			// insert payment
    			if ($status) {
    				if ($subscription_id) {
    					$payment_id = Payment::insertPayment($ds);
    					info_log(' New Completed Payment inserted - Payment ID: '.$payment_id.' paypal subscr_id: '.$subscr_id.' DB subscr_id: '.$subscription_id );
    					// update the nextrebilldate for the subscription
    					$next_rebillTS = Subscription::getNextRebillDate($subscr_id, $payment_date_ts);
                    	$next_rebill = gmdate("Y-m-d",$next_rebillTS);
    					Subscription::updateSubscriptionRebillDate($subscr_id, $next_rebill);
    					info_log(' Rebill date updated Subscription ID: '.$subscr_id.' rebill date: '.$next_rebill);
    				} else {
    					$subscription_id = Subscription::addSubscription($subscr_id, $user_id);
    					info_log(' Added a new Subscription ID: '.$subscr_id.' id = '.$subscription_id);
    					$ds->set('subscription_id',$subscription_id);
                        $payment_id = Payment::insertPayment($ds);
    					info_log(' New Completed Payment inserted - Payment ID: '.$payment_id.' paypal subscr_id: '.$subscr_id.' DB subscr_id: '.$subscription_id );

    				}
    			}


    			// update the reason of the subscription
    			if (!$status) {
    				if (!$reason) $reason = 'Payment failed';
    				Subscription::updateSubscriptionReason($subscr_id, $reason);
    				info_log(' Reason for subscription termination updated -'.$reason.' '.$subscr_id);
    			}
    		} else if ($txn_type=='subscr_eot')   {
    			// cancel the subscription
    			if (!$reason) $reason = 'End Of Term';
                Subscription::cancelSubscription($subscr_id, $reason);
                info_log(' Subscription cancelled (End of Term) -'.$reason.' '.$subscr_id);
            } else if ($txn_type=='subscr_cancel')   {
                // cancel the subscription
                if (!$reason) $reason = 'User cancelled';
                Subscription::cancelSubscription($subscr_id, $reason);
                info_log(' Subscription cancelled (User cancelled) -'.$reason.' '.$subscr_id);

            } else if ($txn_type=='subscr_failed')   {
                // cancel the subscription
                if (!$reason) $reason = 'Failed';
                Subscription::cancelSubscription($subscr_id, $reason);
                info_log(' Subscription cancelled (Failed) -'.$reason.' '.$subscr_id);

    		}
        } else if (strcmp ($res, "INVALID") == 0)  {
   			// log for manual investigation
   			$str =  date('YYYY-MM-DD').' :: Error in subscription: subscr_id='.$subscr_id."\n";
   			if($ff = fopen("logs/paypal.errors.log.txt",'a')) {
    			fwrite($ff, $str);
    			fwrite($ff,'Request data:'."\n".$req."\n");
    			fclose($ff);
  			}

  			err_log($str);
		}

		fclose ($fp);

	}
}


function info_log($str)   {
  if(defined('PAYPAL_DEBUG') && PAYPAL_DEBUG>0)   {
   $md = date('d_M');
   $txn_type = $_POST['txn_type'];

   $fname = "logs/paypal.info.log.".$md.'.'.$txn_type.".html";
   if($ff = fopen($fname,'a'))    {
    fwrite($ff,date('Y-m-d h:i:s').' :: '.$str."<br>\n");
    fclose($ff);
    //print $str."<BR>\n";
   }

   //print $str."<BR>\n";

  }
}

function err_log($str)  {
 if(defined('PAYPAL_DEBUG') && PAYPAL_DEBUG>0)  {
    print "<font color=\"red\">";
 	print "ERROR:".$str."<BR>\n";
    print "</font>\n";
 }
}

function event_log()   {
  if(defined('PAYPAL_DEBUG') && PAYPAL_DEBUG>0)  {
    $md = date('d_M');
   	$txn_type = $_POST['txn_type'];
   	$subscr_id = $_POST['subscr_id'];
   	$fname = "logs/paypal.event.log.".$md.".html";
    if($ff = fopen($fname,'a'))    {
    	fwrite($ff,date('Y-m-d h:i:s').' :: '.$txn_type." : ".$subscr_id."<br>\n");
    	fclose($ff);
    }
  }
}

?>